package com.example.tys.baseapplication.View.recycleView;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.View;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * RecyclerView的基础Adapter
 *
 * @param <DataType> 数据类型
 * @param <VH>       继承于BaseViewHolder的类型 {@link BaseViewHolder}
 * @author tys
 * @date 2017/10/9
 */
public abstract class BaseAdapter<DataType, VH extends BaseViewHolder> extends RecyclerView.Adapter<VH> {

    protected ArrayList<DataType> mData;
    protected Context context;
    protected @Nullable OnItemClickListen mItemClickListen;
    protected @Nullable OnLongItemClickListen mLongItemClickListen;

    protected BaseAdapter(Context context, ArrayList<DataType> mData) {
        this.mData = mData;
        this.context = context;
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    /**
     * 获取数据集合
     *
     * @return
     */
    public List<DataType> getData() {
        return mData;
    }

    /**
     * 获取指定位置的数据
     *
     * @param position
     * @return
     */
    public DataType getData(int position) {
        if (position >= mData.size()) {
            return null;
        }
        return mData.get(position);
    }

    /**
     * 末尾添加数据(没有通知数据更新) {@link RecyclerView.Adapter#notifyDataSetChanged()}
     *
     * @param data 要添加的数据集合
     */
    public void addData(DataType data) {
        mData.add(data);
    }

    /**
     * 末尾批量添加数据(没有通知数据更新) {@link RecyclerView.Adapter#notifyDataSetChanged()}
     *
     * @param data 要添加的数据集合
     */
    public void addData(@NonNull List<DataType> data) {
        mData.addAll(data);
    }

    /**
     * 末尾批量添加数据并且通知更改  {@link ArrayList#addAll(Collection)}
     *
     * @param data 要添加的数据集合
     */
    public void addDataAndNotify(@NonNull List<DataType> data) {
        int start = mData.size();
        mData.addAll(data);
        notifyItemRangeChanged(start, data.size());
    }

    /**
     * 末尾添加数据并且通知更改 {@link ArrayList#add(Object)}
     *
     * @param data 要添加的数据
     */
    public void addDataAndNotify(DataType data) {
        mData.add(data);
        notifyItemChanged(mData.size());
    }

    /**
     * 指定位置添加数据并且通知更改
     *
     * @param index 数据添加的位置 {@link ArrayList#add(int, Object)}
     * @param data  添加的数据
     */
    public void addDataAndNotify(int index, DataType data) {
        mData.add(index, data);
        notifyItemChanged(index);
    }

    /**
     * 指定位置添加数据
     *
     * @param index 数据添加的位置 {@link ArrayList#add(int, Object)}
     * @param data  添加的数据
     */
    public void addData(int index, DataType data) {
        mData.add(index, data);
    }

    /**
     * 刪除指定位置数据并且通知更改
     *
     * @param index 删除数据的位置([0,size)){@link ArrayList#remove(int)}
     * @return true 删除成功, false 删除失败(index>=size)
     */
    public boolean removeDataAndNotify(int index) {
        if (index >= mData.size()) {
            return false;
        }
        mData.remove(index);
        notifyItemRemoved(index);
        return true;
    }

    /**
     * 删除数据并通知更改
     *
     * @param data 要删除的数据
     * @return true 刪除成功, false 刪除失败(不存在该数据)
     */
    public boolean removeDataAndNotify(DataType data) {
        int index = mData.indexOf(data);
        if (index < 0) {
            return false;
        }
        return removeDataAndNotify(index);
    }

    /**
     * 批量删除数据并通知更改(刪除mData中存在的数据)。不能准确得到删除的位置，因此
     * 用{@link RecyclerView.Adapter#notifyDataSetChanged}通知数据改变
     *
     * @param data 要删除数据集合
     * @return 数据是否发生变化
     */
    public boolean removeDataAndNotify(@NonNull List<DataType> data) {
        if (mData.removeAll(data)) {
            notifyDataSetChanged();
            return true;
        }
        return false;
    }

    public DataType removeData(int index) {
        return mData.remove(index);
    }

    /**
     * 清空数据
     */
    public void cleanData() {
        mData.clear();
        notifyDataSetChanged();
    }

    public boolean isEmpty(){
        return mData.isEmpty();
    }

    /**
     * 设置Item的单击事件
     *
     * @param mItemClickListen {@link OnItemClickListen}
     * @return {@link BaseAdapter}
     */
    public BaseAdapter<DataType, VH> setItemClickListen(OnItemClickListen mItemClickListen) {
        this.mItemClickListen = mItemClickListen;
        return this;
    }

    /**
     * 设置Item的单击事件
     *
     * @param mLongItemClickListen {@link OnLongItemClickListen}
     * @return {@link BaseAdapter}
     */
    public BaseAdapter<DataType, VH> setLongItemClickListen(OnLongItemClickListen mLongItemClickListen) {
        this.mLongItemClickListen = mLongItemClickListen;
        return this;
    }

    public interface OnItemClickListen {
        void onItemClick(View itemView, int position);
    }

    public interface OnLongItemClickListen {
        void onLongItemClick(View itemView, int position);
    }

}
